/**
  ******************************************************************************
  * @file    Project/main.c 
  * @author  MCD Application Team
  * @version V2.3.0
  * @date    16-June-2017
  * @brief   Main program body
   ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */ 


/* Includes ------------------------------------------------------------------*/
#include "stm8s_conf.h"
#include "board_conf.h"
#include "user_mb_app.h"
#include "utils.h"

/* Global variables ----------------------------------------------------------*/
device_parameters_t device_parameters;

/* Private defines -----------------------------------------------------------*/
/* Static variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void board_init(void);

/* Main function -------------------------------------------------------------*/
void main(void)
{
    uint8_t VTimer[3] = {0, 0, 0};
    
    /* Configure the HSI prescaler to the optimal value */
    CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);

    board_init();

    eMBInit(MB_RTU, 
            device_parameters.offset_addr + (uint16_t)read_config_address(), 
            1, 
            opt_to_baudrate(device_parameters.baudrate_opt), 
            MB_PAR_NONE);
    
    eMBEnable();

    /* Infinite loop */
    while (1) {
        eMBPoll();
        
        if (TIM2_GetFlagStatus(TIM2_FLAG_UPDATE) == SET) {
            TIM2_ClearFlag(TIM2_FLAG_UPDATE);
            
            VTimer[0]++;
            VTimer[1]++;
            VTimer[2]++;
            
            if (VTimer[0] > 2) {
                VTimer[0] = 0;
            }
            if (VTimer[1] > 10) {
                VTimer[1] = 0;
                
                led_ctrl();
            }
            if (VTimer[2] > 100) {
                VTimer[2] = 0;
            }
        }
    }
  
}

/* Private functions ---------------------------------------------------------*/
static void board_init(void)
{
    TIM2_Prescaler_TypeDef prescaler = TIM2_PRESCALER_16;
    uint16_t period = 4999;
    
    /* Configure the LED0 pin. */
    GPIO_Init(LED0_PORT, LED0_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    /* Configure the OUTPUT pins. */
    GPIO_Init(OUT1_PORT, OUT1_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    GPIO_Init(OUT2_PORT, OUT2_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    GPIO_Init(OUT3_PORT, OUT3_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    GPIO_Init(OUT4_PORT, OUT4_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    GPIO_Init(OUT5_PORT, OUT5_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    GPIO_Init(OUT6_PORT, OUT6_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    GPIO_Init(OUT7_PORT, OUT7_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    GPIO_Init(OUT8_PORT, OUT8_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    /* Configure the INPUT pins. */
    GPIO_Init(IN1_PORT, IN1_PIN, GPIO_MODE_IN_FL_NO_IT);
    GPIO_Init(IN2_PORT, IN2_PIN, GPIO_MODE_IN_FL_NO_IT);
    GPIO_Init(IN3_PORT, IN3_PIN, GPIO_MODE_IN_FL_NO_IT);
    GPIO_Init(IN4_PORT, IN4_PIN, GPIO_MODE_IN_FL_NO_IT);
    GPIO_Init(IN5_PORT, IN5_PIN, GPIO_MODE_IN_FL_NO_IT);
    GPIO_Init(IN6_PORT, IN6_PIN, GPIO_MODE_IN_FL_NO_IT);
    GPIO_Init(IN7_PORT, IN7_PIN, GPIO_MODE_IN_FL_NO_IT);
    GPIO_Init(IN8_PORT, IN8_PIN, GPIO_MODE_IN_FL_NO_IT);
    /* Configure the UART pins. */
    
    /* Configure the RS485 DE/nRE pin. */
//    GPIO_Init(RS485_DR_PORT, RS485_DR_PIN, GPIO_MODE_OUT_PP_LOW_SLOW);
    
    /* Configure UNUSED pins as input with internal pull-up resistor. */
    GPIO_Init(GPIOB, GPIO_PIN_1, GPIO_MODE_IN_PU_NO_IT);
    GPIO_Init(GPIOB, GPIO_PIN_1, GPIO_MODE_IN_PU_NO_IT);
    GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_IN_PU_NO_IT);
    GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_IN_PU_NO_IT);
    GPIO_Init(GPIOC, GPIO_PIN_2, GPIO_MODE_IN_PU_NO_IT);
    GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_IN_PU_NO_IT);
    GPIO_Init(GPIOD, GPIO_PIN_7, GPIO_MODE_IN_PU_NO_IT);
    GPIO_Init(GPIOE, GPIO_PIN_5, GPIO_MODE_IN_PU_NO_IT);
    
    /* Configure TIM2. */
    TIM2_TimeBaseInit(prescaler, period);
    TIM2_Cmd(ENABLE);
    
    /* Define flash programming Time*/
    FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_STANDARD);
    
    /* Get Parameters */
    if (0 != read_parameters((void *)&device_parameters)) {
        /* Use default values */
        device_parameters.baudrate_opt = DEFAULT_BAUDRATE_OPT;
        device_parameters.offset_addr = DEFAULT_OFFSET_ADDR;
        device_parameters.op_mode = DEFAULT_OP_MODE;
        device_parameters.delay_time = DEFAULT_DELAY_TIME;
        
        save_parameters((void *)&device_parameters, PAR_ALL);
    }
        
    /* Enable interrupts. */
    enableInterrupts();
}

#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(u8* file, u32 line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
